

class tree.io.rpc.XML_Proxy extends tree.io.rpc.Proxy
	###
	Proxy for xmlrpc server methods.
	For the standard look here: http://www.xmlrpc.com/spec.
	
	It also needs theese extensions:
	
	http://xmlrpc-c.sourceforge.net/introspection.html
	http://ontosys.com/xml-rpc/extensions.php
	
	events: ['error-occured'],
	
	###
	
	constructor: (url) ->
	    super url
	    @content_type = tree.io.ajax.DATA_FORMAT.xml;
    
    parse_response: (data) ->
        xml = tree.io.formats.xml.load data
        params = xml.getElementsByTagName 'param'

        response = []
        
        parse_scalar = (node) ->

            if node.firstChild.nodeName == 'int'
                return parseInt node.firstChild.firstChild.nodeValue

            else if node.firstChild.nodeName == 'double'
                return parseFloat node.firstChild.firstChild.nodeValue

            else if node.firstChild.nodeName == 'string'

                return node.firstChild.firstChild.nodeValue

            else if node.firstChild.nodeName == 'boolean'

                if node.firstChild.firstChild.nodeValue == '1'
                    return true
                else
                    return false
                        
            else if node.firstChild.nodeName == 'nil'
                return null
        
        parse_array = (node) ->
            (parse_object(item) for item in node.firstChild.childNodes)
        
        parse_object = (param) ->
            node = null
            for node in param.childNodes
                if param.childNodes[i].nodeName != '#text'
                    node = param.childNodes[i]
                    break

            if node.nodeName == 'value'
                return parse_scalar node
                
            else if node.nodeName == 'array'
                return parse_array node

        ###
        fault:
        
        <fault>
            <value>
                <struct>
                    <member>
                        <name>faultCode</name>
                        <value><int>4</int></value>
                    </member>
                    <member>
                        <name>faultString</name>
                        <value><string>Too many parameters.</string></value>
                    </member>
                </struct>
            </value>
        </fault>

        ###
        if params.length == 0
            error = {}
            members = xml.getElementsByTagName('member')
            for member in members
                name = ''
                value = ''
                for node in member.childNodes
                    if member.childNodes[i2].nodeName == 'name'
                        name = node.firstChild.nodeValue
                    
                    else if member.childNodes[i2].nodeName == 'value'
                        value = node.firstChild.firstChild.nodeValue
                        
                        
                error[name] = value
            
            @emit 'error-occured', error
            return error
        
        
        for param in params
        
            response.push parse_object param
        
        return response
    
    
    create_request: (name, params) ->
    
        format_obj = (value) ->
        
            type = typeof(value)
            if type == 'string' or type == 'number' or type == 'boolean' or value == null
            
                return format_scalar value
            
            else
            #no scalar
            
                if value instanceof Array
                    return format_array value
                
                else
                    return format_hash value
                
        format_hash = (value) ->
        
            t = '<struct>';
            for key, val of value
            
                t += '<member>'
                t += '<name>' + key + '</name>'
                t += format_obj val
                t += '</member>'
            
            return t + '</struct>'
        
        format_array = (value) ->
        
            t = '<array><data>'
            for val in value
            
                t += format_obj val
            
            t += '</array></data>'
            return t
        
        format_scalar = (value) ->
        
            if((typeof value) == 'number')
            
                if String(value).indexOf('.') != -1
                #float
                    return '<value><double>' + String value + '</double></value>'
                
                else
                #number
                    return '<value><int>' + String value + '</int></value>'
                
            
            else if (typeof value) == 'string'
            
                return "<value><string>#{value}</string></value>"
            
            else if (typeof value) == 'boolean'
            
                val = value
                if val
                    value = 1
                
                else
                    value = 0
                
                return "<value><boolean>#{value}</boolean></value>"
            
            else if value == null
            
                return '<value><nil/></value>'
            
            else
                throw 'invalid type given'
                
        request = '<?xml version="1.0"?><methodCall>'
        request += "<methodName>#{name}</methodName>"
        request += '<params>'
        for value in params
            request += '<param>'
            request += format_obj value
            request += '</param>'
        
        request += '</params></methodCall>'
        return request

